#ifndef TRANS_HPP
#define TRANS_HPP
#include "error.hpp"
#include "types.hpp"
#include <string>
#include <map>
#include <vector>

using namespace std;

// Estrutura auxiliar para gerar código para atribuição
// de vetores. Com esta estrutura é possível gerar
// facilmente o código necessário para inicializar
// arrays, vectors e sets de intervalo.
class HomoList {
private:
    static bool           _codeready;
    static Type*          _type;
    static string         _code;
    static vector<string> _elements;
public:
    // Obtém o código de atribuição de vetores.
    static string code   (string var);
    // Obtém o tipo subjacente deste vetor.
    static Type*  type   (void);
    // Adiciona uma variável à lista. Uma verificação
    // é feita para garantir que o tipo da mesma seja válido.
    // Caso contrário, um erro semântico é gerado.
    static void   addvar (Properties& var);
    // Esvazia a lista para que uma nova possa ser
    // gerada. Nesta forma, apenas a atribuição de
    // vetores unidimensionais é suportada.
    static void   reset  (void);
    // Obtém o tamanho atual da lista.
    static int    length (void);
};

/*
 * Gerenciador de labels. Monitora a criação de labels para diversas instruções.
 * Para obter uma label basta chamar um dos métodos new...label() e utilizar o
 * índice retornado pelo mesmo com os outros métodos para a instrução
 * correspondente.
 */
class Labels {
private:
    static int _iflabels;
    static int _forlabels;
    static int _looplabels;
    static int _functionlabels;
public:
    static int    iflabels();
    static int    newiflabel();
    static string then(int);
    static string endif(int);
    static int    forlabels();
    static int    newforlabel();
    static string fortest(int);
    static string forexit(int);
    static int    looplabels();
    static int    newlooplabel();
    static string looptest(int);
    static string loopbody(int);
    static string loopexit(int);
    static string functionexit(int);

};

// Rastreia um token da entrada contruindo o nó apropriado na árvore de
// derivação.
void traceToken(const char* token, Type* type = NULL);

#endif /* TRANS_HPP */
